package cn.stylefeng.guns.sys.modular.system.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.stylefeng.guns.base.auth.context.LoginContextHolder;
import cn.stylefeng.guns.base.pojo.page.LayuiPageFactory;
import cn.stylefeng.guns.base.pojo.page.LayuiPageInfo;
import cn.stylefeng.guns.sys.core.exception.BusException;
import cn.stylefeng.guns.sys.core.exception.enums.BusExceptionEnum;
import cn.stylefeng.guns.sys.modular.system.entity.Mdzx;
import cn.stylefeng.guns.sys.modular.system.entity.ZxYusuan;
import cn.stylefeng.guns.sys.modular.system.mapper.MdzxMapper;
import cn.stylefeng.guns.sys.modular.system.mapper.ZxYusuanMapper;
import cn.stylefeng.guns.sys.modular.system.model.params.MdzxParam;
import cn.stylefeng.guns.sys.modular.system.model.params.ZxYusuanParam;
import cn.stylefeng.guns.sys.modular.system.model.result.MdzxResult;
import cn.stylefeng.guns.sys.modular.system.model.result.ZxYusuanResult;
import cn.stylefeng.guns.sys.modular.system.service.MdzxService;
import cn.stylefeng.guns.sys.modular.system.service.ZxYusuanService;
import cn.stylefeng.roses.core.reqres.response.ErrorResponseData;
import cn.stylefeng.roses.core.reqres.response.ResponseData;
import cn.stylefeng.roses.core.reqres.response.SuccessResponseData;
import cn.stylefeng.roses.core.util.ToolUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 装修预算表 服务实现类
 * </p>
 *
 * @author jiangge
 * @since 2020-11-02
 */
@Service
public class ZxYusuanServiceImpl extends ServiceImpl<ZxYusuanMapper, ZxYusuan> implements ZxYusuanService {
    Logger logger = LoggerFactory.getLogger(ZxYusuanServiceImpl.class);

    @Resource
    private MdzxMapper mdzxMapper;
    @Resource
    private MdzxService mdzxService;
    @Resource
    private ZxYusuanService zxYusuanService;
    @Resource
    private ZxYusuanMapper zxYusuanMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(ZxYusuanParam param) {
        ZxYusuan entity = getEntity(param);
        entity.setCreateUser(LoginContextHolder.getContext().getUserId());
        entity.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
        this.save(entity);
        //增加一条装修预算数据，就重新汇总对应门店的预算合计到门店装修表
        //预算合计
        BigDecimal danjia= param.getDanjia()==null?BigDecimal.ZERO:param.getDanjia();
        mdzxService.calculateChengbenAndYusuan(param.getBtyZxMdzxId(),danjia);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(ZxYusuanParam param) {
        ZxYusuan yuSuan = this.getById(getKey(param));
//        this.removeById(getKey(param));

        //逻辑删除
        yuSuan.setDelFlag(1);
        yuSuan.setUpdateUser(LoginContextHolder.getContext().getUserId());
        yuSuan.setUpdateUserName(LoginContextHolder.getContext().getUser().getName());
        this.updateById(yuSuan);

        //重新计算门店装修数据
        BigDecimal danjia= param.getDanjia()==null?BigDecimal.ZERO:param.getDanjia();
        mdzxService.calculateChengbenAndYusuan(yuSuan.getBtyZxMdzxId(),danjia);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(ZxYusuanParam param) {
        ZxYusuan oldEntity = getOldEntity(param);
        ZxYusuan newEntity = getEntity(param);
        ToolUtil.copyProperties(newEntity, oldEntity);
        newEntity.setUpdateUser(LoginContextHolder.getContext().getUserId());
        newEntity.setUpdateUserName(LoginContextHolder.getContext().getUser().getName());

        Mdzx mdzx = this.mdzxMapper.selectById(newEntity.getBtyZxMdzxId());
        BigDecimal mianji;
        BigDecimal price = BigDecimal.ZERO;
        BigDecimal jine= BigDecimal.ZERO;
        BigDecimal ysje;
        BigDecimal danjia=null;
        if(ToolUtil.isNotEmpty(mdzx)&&ToolUtil.isNotEmpty(mdzx.getMianji())){
            mianji=new BigDecimal(mdzx.getMianji());
            if(mianji.compareTo(new BigDecimal(200))==-1){
                jine=new BigDecimal(80000);
            }else if(mianji.compareTo(new BigDecimal(200))!=-1 &&mianji.compareTo(new BigDecimal(220))==-1){
                jine=new BigDecimal(100000);
            }else if(mianji.compareTo(new BigDecimal(220))!=-1 &&mianji.compareTo(new BigDecimal(240))==-1){
                jine=new BigDecimal(120000);
            }
            else{
                jine=new BigDecimal(140000);
            }
//            //获取单价
            //danjia= newEntity.getDanjia()==null?BigDecimal.ZERO:newEntity.getDanjia();
            if(ToolUtil.isNotEmpty(newEntity.getDanjia())&&newEntity.getDanjia().compareTo(BigDecimal.ZERO)>0){
                danjia=newEntity.getDanjia();
                newEntity.setDanjia(newEntity.getDanjia());
                price=mianji.multiply(newEntity.getDanjia());
                newEntity.setJine(price);
            }else{
               zxYusuanMapper.updateByDanjia(newEntity.getBtyZxYusuanId());
            }

            //jine=jine.add(price);
            //根据面积更新桌椅金额
            if((param.getJine()==null?BigDecimal.ZERO:param.getJine()).compareTo(BigDecimal.ZERO)==1&&param.getXuhao()==31){
                jine=param.getJine();
                ZxYusuan zxYusuan = new ZxYusuan();
                zxYusuan.setJine(jine);
                zxYusuanService.update(zxYusuan, new QueryWrapper<ZxYusuan>().eq("bty_zx_mdzx_id", newEntity.getBtyZxMdzxId())
                        .eq("xuhao", "31"));
            }else {
                ZxYusuan yusuan=zxYusuanService.getOne(new QueryWrapper<ZxYusuan>().eq("bty_zx_mdzx_id", newEntity.getBtyZxMdzxId()).eq("xuhao", "31"));
                BigDecimal je=BigDecimal.ZERO;
                if(ToolUtil.isNotEmpty(yusuan)){
                     je=yusuan.getJine()==null?BigDecimal.ZERO:yusuan.getJine();
                }
                if(je.compareTo(BigDecimal.ZERO)!=1){
                    ZxYusuan zxYusuan = new ZxYusuan();
                    zxYusuan.setJine(jine);
                    zxYusuanService.update(zxYusuan, new QueryWrapper<ZxYusuan>().eq("bty_zx_mdzx_id", newEntity.getBtyZxMdzxId())
                            .eq("xuhao", "31"));
                }

            }
        }


        //this.updateById(newEntity);
        zxYusuanMapper.updateByYusuan(newEntity);
        //重新计算门店装修数据
        if (oldEntity.getBtyZxMdzxId().equals(newEntity.getBtyZxMdzxId())) {
            //1.修改前后是同一个店
            mdzxService.calculateChengbenAndYusuan(param.getBtyZxMdzxId(),danjia);
        } else {
            //2.修改前后不是同一个店
            mdzxService.calculateChengbenAndYusuan(oldEntity.getBtyZxMdzxId(),danjia);
            mdzxService.calculateChengbenAndYusuan(newEntity.getBtyZxMdzxId(),danjia);
        }
    }

    @Override
    public ZxYusuanResult findBySpec(ZxYusuanParam param) {
        return null;
    }

    @Override
    public List<ZxYusuanResult> findListBySpec(ZxYusuanParam param) {
        return null;
    }

    @Override
    public LayuiPageInfo findPageBySpec(ZxYusuanParam param) {
        Page pageContext = getPageContext();
       //根据门店装修id获取门店总面积
        Long mdZxId=param.getBtyZxMdzxId();
        Mdzx mdzx=mdzxMapper.selectById(mdZxId);
        BigDecimal mianji;
        BigDecimal jine=new BigDecimal(0);
        if(ToolUtil.isNotEmpty(mdzx)&&ToolUtil.isNotEmpty(mdzx.getMianji())){
            mianji=new BigDecimal(mdzx.getMianji());
            if(mianji.compareTo(new BigDecimal(190))==-1){
                jine=new BigDecimal(80000);
            }else if(mianji.compareTo(new BigDecimal(190))!=-1 &&mianji.compareTo(new BigDecimal(220))==-1){
                jine=new BigDecimal(120000);
            }else{
                jine=new BigDecimal(140000);
            }
        }
        //IPage page = this.baseMapper.customPageList(pageContext, param);

        Page<Map<String, Object>> page = this.baseMapper.customPageMapList(pageContext, param);

        List<Map<String,Object>> mapList=page.getRecords();
        for(Map<String,Object> map:mapList){
            String xiangmu=map.get("xiangmu")==null?"0":map.get("xiangmu").toString();
            String  jines=map.get("jine")==null?"0.00":map.get("jine").toString();
           if(xiangmu.equals("桌椅")&&jines.equals("0.00")){
               map.put("jine",jine);
           }
        }

        return LayuiPageFactory.createPageInfo(page);
    }

    @Override
    public List<Map<String, Object>> listExport(Long btyZxMdzxId) {
        return this.baseMapper.listExport(btyZxMdzxId);
    }

    @Override
    public Integer getMaxXuhaoByMdId(Long btyZxMdzxId) {
        Integer maxNum = mdzxMapper.getMaxXuhaoByMdId(btyZxMdzxId);
        return maxNum;
    }

    private Serializable getKey(ZxYusuanParam param) {
        return param.getBtyZxYusuanId();
    }

    private Page getPageContext() {
        return LayuiPageFactory.defaultPage();
    }

    private ZxYusuan getOldEntity(ZxYusuanParam param) {
        return this.getById(getKey(param));
    }

    private ZxYusuan getEntity(ZxYusuanParam param) {
        ZxYusuan entity = new ZxYusuan();
        ToolUtil.copyProperties(param, entity);
        return entity;
    }


    private Workbook getWorkBook(InputStream inputStream) throws IOException {
        Workbook wb = null;
        try {
            wb = new XSSFWorkbook(inputStream);
            return wb;

        } catch (Exception e) {
            wb = new HSSFWorkbook(inputStream);
            return wb;
        }

    }

    //预算导入
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData batchImport(String fileName, MultipartFile file) throws Exception {

        if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
            return new ErrorResponseData("上传文件格式不正确");
        }
        InputStream is = file.getInputStream();
        Workbook wb = getWorkBook(is);
        Sheet sheet = wb.getSheetAt(0);
        Row dmrow = sheet.getRow(1);

        //获取所有的门店装修的门店信息
        MdzxParam mdzxParam = new MdzxParam();
        mdzxParam.setContainsCopy("no");
        List<MdzxResult> mdzxResultList = mdzxService.customList(mdzxParam);
        Map<String, Long> mdzxMap = mdzxResultList.stream().collect(Collectors.toMap(MdzxResult::getBtyBrandIdView, MdzxResult::getBtyZxMdzxId));

        String dianMing = dmrow.getCell(1).getStringCellValue();

        if (ToolUtil.isEmpty(dianMing)) {
            return ErrorResponseData.error("门店信息不允许为空");
        }

        //工程项目中已经存在，门店装修中不存在，自动创建门店装修信息
        if (mdzxMap.get(dianMing) == null) {
            return new ErrorResponseData("导入失败，门店：" + dianMing + "，在装修门店中不存在，请先添加装修门店信息。");
        }

        List<ZxYusuanParam> yslist = new ArrayList<ZxYusuanParam>();
        BigDecimal yujiTouzi=null;
        int lastRowNum = sheet.getLastRowNum();
        for (int r = 3; r <= lastRowNum; r++) {
            Row row = sheet.getRow(r);
            if (row == null) {
                continue;
            }
            ResponseData xuhao = getStringValue(row.getCell(0));
            if(xuhao.getData().equals("总计")){
                ResponseData yjtz = getDoubleValue(row.getCell(3));
                double d = (double) yjtz.getData();
                yujiTouzi = yjtz == null ? BigDecimal.ZERO : new BigDecimal(d).setScale(4, BigDecimal.ROUND_UP);
                break;
            }
            Integer xh = row.getCell(0) == null ? 0 : (Integer) getIntegerValue(row.getCell(0)).getData();
            if(xh==0){
                break;
            }
            //项目名称
            String item = row.getCell(1) == null ? "" : (String) getStringValue(row.getCell(1)).getData();
            //金额
            Cell cell2 = row.getCell(2);
            ResponseData typeData = getDoubleValue(cell2);
            if (typeData.getCode() != 200) {
                return new ErrorResponseData("导入失败，第" + (r + 1) + "行" + 3 + "列,金额不是数字");
            }
            double d = (double) typeData.getData();
            BigDecimal jine = cell2 == null ? BigDecimal.ZERO : new BigDecimal(d).setScale(4, BigDecimal.ROUND_UP);


            ZxYusuanParam ys = new ZxYusuanParam();
            ys.setXiangmu(item);
            ys.setJine(jine);
            ys.setCreateTime(new Date());
            ys.setXuhao(Integer.valueOf(xh));
            ys.setCreateUser(LoginContextHolder.getContext().getUserId());
            ys.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
            ys.setBtyZxMdzxId(mdzxMap.get(dianMing));
            yslist.add(ys);
        }

        if (CollectionUtil.isNotEmpty(yslist)) {
            //同步预计投资
            Mdzx mdzx = mdzxService.getById(mdzxMap.get(dianMing));
            mdzx.setYujiTouzi(yujiTouzi);
            mdzx.setYusuanHeji(new BigDecimal("0.00"));
            mdzxService.saveOrUpdate(mdzx);


            this.deleteByHead(mdzxMap.get(dianMing));

            for (ZxYusuanParam yusuan : yslist) {
                //此添加会重新计算预算总计
                this.add(yusuan);
            }

            return SuccessResponseData.success("预算信息导入成功");
        }

        return ErrorResponseData.error("导入预算信息失败!");
    }

    private void deleteByHead(Long aLong) {
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("bty_zx_mdzx_id",aLong);
        this.baseMapper.deleteByMap(map);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData yusuanSheet(Sheet sheet,Long zxmdid){
        Row dmrow = sheet.getRow(1);

        //获取所有的门店装修的门店信息
       /* MdzxParam mdzxParam = new MdzxParam();
        mdzxParam.setContainsCopy("no");
        List<MdzxResult> mdzxResultList = mdzxService.customList(mdzxParam);
        Map<String, Long> mdzxMap = mdzxResultList.stream().collect(Collectors.toMap(MdzxResult::getBtyBrandIdView, MdzxResult::getBtyZxMdzxId));
          String dianMing = dmrow.getCell(1).getStringCellValue();
      if (ToolUtil.isEmpty(dianMing)) {
            return ErrorResponseData.error("门店信息不允许为空");
        }
        if (mdzxMap.get(dianMing) == null) {
            return new ErrorResponseData("导入失败，门店：" + dianMing + "，在装修门店中不存在，请先添加装修门店信息。");
        }*/

        List<ZxYusuanParam> yslist = new ArrayList<ZxYusuanParam>();

        int lastRowNum = sheet.getLastRowNum();
        for (int r = 3; r <= lastRowNum; r++) {
            Row row = sheet.getRow(r);
            if (row == null) {
                continue;
            }

            Integer xh = row.getCell(0) == null ? 0 : (Integer) getIntegerValue(row.getCell(0)).getData();
            if(xh==0){
                break;
            }
            //项目名称
            String item = row.getCell(1) == null ? "" : (String) getStringValue(row.getCell(1)).getData();
            //金额
            Cell cell2 = row.getCell(2);
            ResponseData typeData = getDoubleValue(cell2);
            if (typeData.getCode() != 200) {
                return new ErrorResponseData("导入失败，第" + (r + 1) + "行" + 3 + "列,金额不是数字");
            }
            double d = (double) typeData.getData();
            BigDecimal jine = cell2 == null ? BigDecimal.ZERO : new BigDecimal(d).setScale(2, BigDecimal.ROUND_UP);


            ZxYusuanParam ys = new ZxYusuanParam();
            ys.setXiangmu(item);
            ys.setJine(jine);
            ys.setCreateTime(new Date());
            ys.setXuhao(Integer.valueOf(xh));
            ys.setCreateUser(LoginContextHolder.getContext().getUserId());
            ys.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
            ys.setBtyZxMdzxId(zxmdid);
            yslist.add(ys);
        }

        if (CollectionUtil.isNotEmpty(yslist)) {
            for (ZxYusuanParam yusuan : yslist) {
                //此添加会重新计算预算总计
                this.add(yusuan);
            }
            return SuccessResponseData.success("预算信息导入成功");
        }
        return ErrorResponseData.error("导入预算信息失败!");
    }

    @Override
    public ResponseData copyYusn(ZxYusuanParam param) {

        return null;
    }

    /**
     * 初始化预算数据，如有数据将会覆盖
     *
     * @param zxYusuanParam
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResponseData initYusuanData(ZxYusuanParam zxYusuanParam) {

        //TODO-1 要先选中要初始化数据的门店
        if (zxYusuanParam.getBtyZxMdzxId() == null) {
            return new ErrorResponseData("初始化失败，请先选择门店");
        }

        //TODO-2 数据已经被锁定，如需操作，请先解锁
        QueryWrapper<Mdzx> wrapper = new QueryWrapper<>();
        wrapper = wrapper.eq("bty_zx_mdzx_id", zxYusuanParam.getBtyZxMdzxId());
        wrapper = wrapper.eq("del_flag", 0);
        List<Mdzx> data = mdzxMapper.selectList(wrapper);
        if (CollectionUtil.isNotEmpty(data)) {
            //已经存在无须添加
            if (data.get(0).getYusuanLock() == 1) {
                return new ErrorResponseData("初始化失败，此店数据已经被锁定，如需操作，请先解锁");
            }
        }

        //TODO-3删除该店已存在数据
        QueryWrapper<ZxYusuan> wrapper2 = new QueryWrapper<>();
        wrapper2 = wrapper2.eq("bty_zx_mdzx_id", zxYusuanParam.getBtyZxMdzxId());
        int deleteCount = this.baseMapper.delete(wrapper2);

        //TODO-4复制预算模板做初始化
        List<ZxYusuanResult> paramlist = this.baseMapper.listYusuantemplateByPinpai(zxYusuanParam.getPinpai());

        if (ToolUtil.isNotEmpty(paramlist)) {
            List<ZxYusuan> yusuanlist = new ArrayList<>();
            for (ZxYusuanResult param1 : paramlist) {
                ZxYusuan ys = new ZxYusuan();
                ys.setXuhao(param1.getXuhao());
                ys.setXiangmu(param1.getXiangmu());
                ys.setJine(param1.getJine());
                ys.setSjdw(param1.getSjdw());
                ys.setDanjia(param1.getDanjia());
                ys.setBtyZxMdzxId(zxYusuanParam.getBtyZxMdzxId());
                ys.setCreateUser(LoginContextHolder.getContext().getUserId());
                ys.setCreateUserName(LoginContextHolder.getContext().getUser().getName());
                ys.setCreateTime(new Date());
                yusuanlist.add(ys);
            }
            boolean b = this.baseMapper.batchAdd(yusuanlist);
            if (!b) {
                logger.error("初始化预算数据失败!");
                throw new BusException(BusExceptionEnum.ERR_COPY_YUSUAN);
            }

        }

        //TODO-5重新计算预算合计（即该店预算数据金额之和）
        BigDecimal danjia= zxYusuanParam.getDanjia()==null?BigDecimal.ZERO:zxYusuanParam.getDanjia();
        mdzxService.calculateChengbenAndYusuan(zxYusuanParam.getBtyZxMdzxId(),danjia);


        return ResponseData.success();
    }


    private ResponseData getDoubleValue(Cell cell) {
        if (cell == null) {
            return new SuccessResponseData(new Double(0));
        }

        CellType cellType = cell.getCellType();
        if (cellType == CellType.NUMERIC) {
            //数值型
            double numericCellValue = cell.getNumericCellValue();
            return new SuccessResponseData(numericCellValue);
        } else if (cellType == CellType.BLANK) {
            //空值型
            return new SuccessResponseData(new Double(0));
        } else if (cellType == CellType.FORMULA) {
            //公式型
            cell.setCellType(CellType.STRING);
            String str = cell.getStringCellValue();
            return new SuccessResponseData(Double.parseDouble(str));
        } else {
            //字符串型
            String str = cell.getStringCellValue();
            if(str.trim().equals("")){
                str="0";
            }
            try {
                double value = Double.parseDouble(str);
                return new SuccessResponseData(value);
            } catch (NumberFormatException ex) {
            }
            return new ErrorResponseData("不是数字");
        }
    }

    private ResponseData getIntegerValue(Cell cell) {
        if (cell == null) {
            return new SuccessResponseData(new Integer(0));
        }
        CellType cellType = cell.getCellType();
        if (cellType == CellType.NUMERIC) {
            //数值型
            Double numericCellValue = cell.getNumericCellValue();

            int valInt = Double.valueOf(numericCellValue).intValue();
            return new SuccessResponseData(valInt);
        } else if (cellType == CellType.BLANK) {
            //空值型
            return new SuccessResponseData(new Integer(0));
        } else if (cellType == CellType.FORMULA) {
            //公式型
            cell.setCellType(CellType.STRING);
            String str = cell.getStringCellValue();
            return new SuccessResponseData(Integer.parseInt(str));
        } else {
            //字符串型
            String str = cell.getStringCellValue();
            if(str.trim().equals("")){
                str="0";
            }
            try {
                double value = Double.parseDouble(str);
                int valInt = Double.valueOf(value).intValue();
                return new SuccessResponseData(valInt);
            } catch (NumberFormatException ex) {
            }
            return new ErrorResponseData("不是数字");
        }
    }

    private ResponseData getStringValue(Cell cell) {
        if (cell == null) {
            return new SuccessResponseData("");
        }

        CellType cellType = cell.getCellType();
        if (cellType == CellType.NUMERIC) {
            Double numericCellValue = cell.getNumericCellValue();
            return new SuccessResponseData(numericCellValue.toString());
        } else if (cellType == CellType.BLANK) {
            //空值型
            return new SuccessResponseData("");
        } else {
            String str = cell.getStringCellValue();
            try {
                return new SuccessResponseData(str);
            } catch (NumberFormatException ex) {
            }
            return new ErrorResponseData("解析失败");
        }
    }


}
